package com.m4f.city.business.oauth2.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Logger;

import com.m4f.city.business.domain.oauth2.OAuth2AccessTokenDS;
import com.m4f.city.business.domain.oauth2.OAuth2RefreshTokenDS;
import com.m4f.city.business.oauth2.ifc.OAuth2TokensService;
import com.m4f.gaeweb.business.service.impl.DAOBaseService;
import com.m4f.gaeweb.persistence.dao.ifc.DAOSupport;


public class OAuth2TokensServiceImpl extends DAOBaseService implements OAuth2TokensService {
	
	private static final Logger LOGGER = Logger.getLogger(OAuth2TokensServiceImpl.class.getName());
		
	public OAuth2TokensServiceImpl(DAOSupport dao) {
		super(dao);
	}

	@Override
	public OAuth2AccessTokenDS createAccessToken() {
		return this.DAO.createInstance(OAuth2AccessTokenDS.class);
	}

	@Override
	public OAuth2RefreshTokenDS createRefreshToken() {
		return this.DAO.createInstance(OAuth2RefreshTokenDS.class);
	}

	@Override
	public OAuth2AccessTokenDS getAccessToken(String tokenValue) throws Exception {
		return (OAuth2AccessTokenDS) this.DAO.findEntity(OAuth2AccessTokenDS.class, "accessTokenValue == accessTokenValueParam", 
				"String accessTokenValueParam", new String[]{tokenValue});
	}

	@Override
	public OAuth2RefreshTokenDS getRefreshToken(String tokenValue) throws Exception {
		return (OAuth2RefreshTokenDS) this.DAO.findEntity(OAuth2RefreshTokenDS.class, "refreshTokenValue == refreshTokenValueParam", 
				"String refreshTokenValueParam", new String[]{tokenValue});
	}

	@Override
	public void removeAccessToken(String tokenValue) throws Exception {
		OAuth2AccessTokenDS accessToken = (OAuth2AccessTokenDS) this.DAO.findEntity(OAuth2AccessTokenDS.class, "accessTokenValue == accessTokenValueParam", 
				"String accessTokenValueParam", new String[]{tokenValue});
		this.DAO.delete(accessToken);
	}

	@Override
	public void removeRefreshToken(String tokenValue) throws Exception {
		OAuth2RefreshTokenDS refreshToken = (OAuth2RefreshTokenDS) this.DAO.findEntity(OAuth2RefreshTokenDS.class, "refreshTokenValue == refreshTokenValueParam", 
				"String refreshTokenValueParam", new String[]{tokenValue});
		this.DAO.delete(refreshToken);		
	}

	@Override
	public void save(OAuth2AccessTokenDS accessToken) throws Exception {
		this.DAO.saveOrUpdate(accessToken);
	}

	@Override
	public void save(OAuth2RefreshTokenDS refreshToken) throws Exception {
		this.DAO.saveOrUpdate(refreshToken);
	}

	@Override
	public void removeAccessTokenByRefresToken(String tokenValue) throws Exception {
		OAuth2AccessTokenDS accessToken = (OAuth2AccessTokenDS) this.DAO.findEntity(OAuth2AccessTokenDS.class, "refreshTokenValue == refreshTokenValueParam", 
				"String refreshTokenValueParam", new String[]{tokenValue});
		this.DAO.delete(accessToken);
	}

	@Override
	public void removeAccessToken(Long userId, String clientId)
			throws Exception {
		Collection<OAuth2AccessTokenDS> tokens = this.getAllAccessToken(userId, clientId);
		for(OAuth2AccessTokenDS token : tokens) {
			this.removeAccessToken(token);
		}
	}
	
	@Override
	public void removeRefreshToken(Long userId, String clientId)
			throws Exception {
		Collection<OAuth2RefreshTokenDS> tokens = this.getAllRefreshToken(userId, clientId);
		for(OAuth2RefreshTokenDS token : tokens) {
			this.removeRefreshToken(token);
		}
	}
	
	@Override
	public List<OAuth2AccessTokenDS> getAllAccessToken() throws Exception {
		return this.DAO.findAll(OAuth2AccessTokenDS.class);
	}

	@Override
	public List<OAuth2RefreshTokenDS> getAllRefreshToken() throws Exception {
		return this.DAO.findAll(OAuth2RefreshTokenDS.class);
	}

	@Override
	public void removeAccessToken(OAuth2AccessTokenDS token) throws Exception {
		this.DAO.delete(token);
	}

	@Override
	public void removeRefreshToken(OAuth2RefreshTokenDS token) throws Exception {
		this.DAO.delete(token);		
	}

	@Override
	public Collection<OAuth2AccessTokenDS> getAllAccessToken(Long userId,String clientId)
			throws Exception {
		StringBuffer filter = new StringBuffer();
		//HashMap<String, Object> values = new HashMap<String, Object>();
		List values = new ArrayList();
		StringBuffer params = new StringBuffer();
		
		if(userId != null) {
			filter.append("userId == userIdParam");
			//values.put("typeParam", type.getValue());
			values.add(userId);
			params.append("java.lang.Long userIdParam");
		}
		
		if(clientId != null) {
			if(filter.length() != 0) {
				filter.append(" && ");
				params.append(",");
			}
			filter.append("clientId == clientIdParam");
			//values.put("typeParam", type.getValue());
			values.add(clientId);
			params.append("java.lang.String clientIdParam");
		}
		
		return this.DAO.findEntities(OAuth2AccessTokenDS.class, filter.toString(), 
				params.toString(), values.toArray(), null);
	}

	@Override
	public Collection<OAuth2RefreshTokenDS> getAllRefreshToken(Long userId, String clientId)
			throws Exception {
		StringBuffer filter = new StringBuffer();
		//HashMap<String, Object> values = new HashMap<String, Object>();
		List values = new ArrayList();
		StringBuffer params = new StringBuffer();
		
		if(userId != null) {
			filter.append("userId == userIdParam");
			//values.put("typeParam", type.getValue());
			values.add(userId);
			params.append("java.lang.Long userIdParam");
		}
		
		if(clientId != null) {
			if(filter.length() != 0) {
				filter.append(" && ");
				params.append(",");
			}
			filter.append("clientId == clientIdParam");
			//values.put("typeParam", type.getValue());
			values.add(clientId);
			params.append("java.lang.Long clientIdParam");
		}
		
		return this.DAO.findEntities(OAuth2RefreshTokenDS.class, filter.toString(), 
				params.toString(), values.toArray(), null);
	}
	
	@Override
	public OAuth2AccessTokenDS getAccessToken(Long userId,String clientId)
			throws Exception {
		Collection<OAuth2AccessTokenDS> tokens = this.DAO.findEntitiesByRange(OAuth2AccessTokenDS.class, "userId == userIdParam && clientId == clientIdParam", 
				"java.lang.Long userIdParam, java.lang.String clientIdParam", new Object[]{userId, clientId}, null,0,1);
		
		Iterator<OAuth2AccessTokenDS> it = tokens.iterator(); 
		return it.next();
	}
	
	@Override
	public OAuth2RefreshTokenDS getRefreshToken(Long userId, String clientId)
			throws Exception {
		Collection<OAuth2RefreshTokenDS> tokens = this.DAO.findEntitiesByRange(OAuth2RefreshTokenDS.class, "userId == userIdParam && clientId == clientIdParam", 
				"java.lang.Long userIdParam, java.lang.String clientIdParam", new Object[]{userId, clientId}, null,0,1);
		
		Iterator<OAuth2RefreshTokenDS> it = tokens.iterator(); 
		return it.next();
	}
}